package com.unismc.charge.collector.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.loyo.Request;
import com.gitee.loyo.Result;
import com.gitee.loyo.config.ChargeConst;
import com.gitee.loyo.config.properties.ChargeNotifyProperty;
import com.gitee.loyo.config.properties.ChargeProperties;
import com.gitee.loyo.data.ConnectorStatusInfo;
import com.gitee.loyo.data.Token;
import com.gitee.loyo.enums.ConnectorStatus;
import com.gitee.loyo.enums.LockStatus;
import com.gitee.loyo.enums.ParkStatus;
import com.gitee.loyo.enums.StartChargeSeqStat;
import com.gitee.loyo.post.*;
import com.gitee.loyo.result.*;
import com.unismc.charge.collector.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/evcs/v1/{operatorKey}")
public class ChargingNotificationController {
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Resource
    ChargeProperties chargeProperties;
    @Resource
    ObjectMapper objectMapper;

    @PostMapping("/query_token")
    public Result<Token> queryToken(@PathVariable("operatorKey") String operatorKey,
                                    @RequestBody Request<QueryTokenPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);
        QueryTokenPost data = post.getData();
        try {
            log.info("query_token: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        if (data == null || data.getOperatorId() == null
                || data.getOperatorSecret() == null) {
            Result<Token> result = new Result<>(post);
            result.setRet(4004);
            result.setMsg("请求业务的参数不合法，各接口定义自己的必须参数");
            return result;
        }
        if (!notifyProperty.getOperatorId().equals(data.getOperatorId())) {
            Result<Token> result = new Result<>(post);
            result.setRet(0);
            Token token = new Token();
            token.setOperatorId(notifyProperty.getOperatorId());
            token.setSuccStat(1);
            token.setFailReason(1);
            result.setData(token);
            return result;
        }
        if (!notifyProperty.getOperatorSecret().equals(data.getOperatorSecret())) {
            Result<Token> result = new Result<>(post);
            result.setRet(0);
            Token token = new Token();
            token.setOperatorId(notifyProperty.getOperatorId());
            token.setSuccStat(1);
            token.setFailReason(2);
            result.setData(token);
            return result;
        }

        // 生成令牌
        Result<Token> result = new Result<>(post);
        result.setRet(0);
        Token token = new Token();
        token.setOperatorId(notifyProperty.getOperatorId());
        token.setAccessToken(UUID.randomUUID().toString());
        token.setTokenAvailableTime(24 * 3600);
        result.setData(token);
        // 保存到Redis
        redisTemplate.opsForValue().set(
                ChargeConst.REDIS_TCEC_OPS_TOKEN + notifyProperty.getOperatorId(),
                token,
                24 * 3600
        );
        log.info("OperatorID {} query token: {}", token.getOperatorId(), token.getAccessToken());
        //Object t =
        //redisTemplate.opsForValue().get(ChargeConst.REDIS_TCEC_OPS_TOKEN + notifyProperty.getOperatorId());
        //log.info("redis token:{}",t);
        //String accessToken = t.getAccessToken();
        //log.info("accessToken:{}", accessToken);
        return result;
    }

    @PostMapping("/notification_stationStatus")
    public Result<NotifyStationStatusResult> notifyStationStatus(@PathVariable("operatorKey") String operatorKey,
                                                                 @RequestBody Request<NotifyStationStatusPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);
        try {
            log.info("notification_stationStatus: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ConnectorStatusInfo connectorStatusInfo = null;
        try {
            connectorStatusInfo = post.getData().getConnectorStatusInfo();
            log.info("设备状态变化推送 {}: {}, 地锁{}, 车位{}",
                    connectorStatusInfo.getConnectorId(),
                    ConnectorStatus.valueOf(connectorStatusInfo.getStatus()).getText(),
                    LockStatus.valueOf(connectorStatusInfo.getLockStatus()).getText(),
                    ParkStatus.valueOf(connectorStatusInfo.getParkStatus()).getText()
            );
        } catch (Exception e) {

        }
        SpringUtils.ctx().publishEvent(connectorStatusInfo);
        Result result = new Result(post);
        result.setRet(0);
        NotifyStationStatusResult data = new NotifyStationStatusResult();
        data.setStatus(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @PostMapping("/notification_start_charge_result")
    public Result<NotifyStartChargeResultResult> notifyStartChargeResult(@PathVariable("operatorKey") String operatorKey,
                                                                         @RequestBody Request<NotifyStartChargeResultPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);
        try {
            log.info("notification_start_charge_result: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        NotifyStartChargeResultPost startChargeResultPost = null;
        try {
            startChargeResultPost = post.getData();
            log.info("推送启动充电结果 {}: {}",
                    startChargeResultPost.getConnectorId(),
                    StartChargeSeqStat.valueOf(startChargeResultPost.getStartChargeSeqStat()).getText()
            );
        } catch (Exception e) {

        }
        //SpringUtils.ctx().publishEvent(startChargeResultPost);
        Result result = new Result(post);
        result.setRet(0);
        NotifyStartChargeResultResult data = new NotifyStartChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @PostMapping("/notification_equip_charge_status")
    public Result<NotifyEquipChargeStatusResult> notifyEquipChargeStatus(
            @PathVariable("operatorKey") String operatorKey,
            @RequestBody Request<NotifyEquipChargeStatusPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);

        try {
            log.info("notification_equip_charge_status: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        NotifyEquipChargeStatusPost equipChargeStatusPost = null;
        try {
            equipChargeStatusPost = post.getData();
            log.info("推送充电状态 {}: {}, 电费{}, 服务费{}, 总金额{}",
                    equipChargeStatusPost.getConnectorId(),
                    StartChargeSeqStat.valueOf(equipChargeStatusPost.getStartChargeSeqStat()).getText(),
                    equipChargeStatusPost.getElecMoney(),
                    equipChargeStatusPost.getServiceMoney(),
                    equipChargeStatusPost.getTotalMoney()
            );
        } catch (Exception e) {

        }
        SpringUtils.ctx().publishEvent(equipChargeStatusPost);
        Result result = new Result(post);
        result.setRet(0);
        NotifyStartChargeResultResult data = new NotifyStartChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @PostMapping("/notification_stop_charge_result")
    public Result<NotifyStopChargeResultResult> notifyStopChargeResult(
            @PathVariable("operatorKey") String operatorKey,
            @RequestBody Request<NotifyStopChargeResultPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);

        try {
            log.info("notification_stop_charge_result: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try {
            NotifyStopChargeResultPost equipChargeStatusPost = post.getData();
            log.info("推送停止充电结果 {}: {}",
                    equipChargeStatusPost.getConnectorId(),
                    StartChargeSeqStat.valueOf(equipChargeStatusPost.getStartChargeSeqStat()).getText()
            );
        } catch (Exception e) {

        }
        Result result = new Result(post);
        result.setRet(0);
        NotifyStopChargeResultResult data = new NotifyStopChargeResultResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setSuccStat(0);
        data.setFailReason(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @PostMapping("/notification_charge_order_info")
    public Result<NotifyChargeOrderInfoResult> notifyChargeOrderInfo(
            @PathVariable("operatorKey") String operatorKey,
            @RequestBody Request<NotifyChargeOrderInfoPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);

        try {
            log.info("notification_charge_order_info: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        NotifyChargeOrderInfoPost chargeOrderInfoPost = null;
        try {
            chargeOrderInfoPost = post.getData();
            log.info("推送充电订单 {}: 电费{}, 服务费{}, 总金额{}",
                    chargeOrderInfoPost.getConnectorId(),
                    chargeOrderInfoPost.getTotalElecMoney(),
                    chargeOrderInfoPost.getTotalServiceMoney(),
                    chargeOrderInfoPost.getTotalMoney()
            );
        } catch (Exception e) {

        }
        SpringUtils.ctx().publishEvent(chargeOrderInfoPost);
        Result result = new Result(post);
        result.setRet(0);
        NotifyChargeOrderInfoResult data = new NotifyChargeOrderInfoResult();
        data.setStartChargeSeq(post.getData().getStartChargeSeq());
        data.setConnectorId(post.getData().getConnectorId());
        data.setConfirmResult(0);
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }

    @PostMapping("/check_charge_order")
    public Result<CheckChargeOrderResult> checkChargeOrder(
            @PathVariable("operatorKey") String operatorKey,
            @RequestBody Request<CheckChargeOrderPost> post) {
        ChargeNotifyProperty notifyProperty = chargeProperties.getNotifyProperty(operatorKey);

        try {
            log.info("check_charge_order: {}", objectMapper.writeValueAsString(post));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        try {
            CheckChargeOrderPost checkChargeOrderPost = post.getData();
            log.info("推送订单对账结果信息 {} - {} : 总金额{}, 总电量{}",
                    checkChargeOrderPost.getStartTime(),
                    checkChargeOrderPost.getEndTime(),
                    checkChargeOrderPost.getTotalOrderMoney(),
                    checkChargeOrderPost.getTotalOrderPower()
            );
            if (checkChargeOrderPost.getChargeOrders() != null) {
                for (CheckChargeOrderPost.ChargeOrder chargeOrder : checkChargeOrderPost.getChargeOrders()) {
                    log.info("明细 {}: 总金额{}, 总电量{} ", chargeOrder.getStartChargeSeq(), chargeOrder.getTotalPower(), chargeOrder.getTotalMoney());
                }
            }
        } catch (Exception e) {

        }
        Result result = new Result(post);
        result.setRet(0);
        CheckChargeOrderResult data = new CheckChargeOrderResult();
        data.setCheckOrderSeq(post.getData().getCheckOrderSeq());
        data.setStartTime(post.getData().getStartTime());
        data.setEndTime(post.getData().getEndTime());
        data.setTotalDisputeOrder(0);
        data.setTotalDisputeMoney(0d);
        data.setTotalDisputePower(0d);
        data.setDisputeOrders(Collections.emptyList());
        result.setMsg("请求成功");
        result.setData(data);
        return result;
    }
}
